package com.lipaluma.field.validator.impl.string;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import com.lipaluma.annotations.validations.Validate;
import com.lipaluma.context.Context;
import com.lipaluma.field.validator.strategies.SubStringMatcherValidationStrategy;
import com.lipaluma.xml.validator.XmlContainsValidator;
import com.lipaluma.xml.validator.XmlValidator;

/**
 * Validator util for String field that check if given values are substrings of the field value.<br/>
 * Two strategies can be applied : <br/>
 *  - at least one one the given value must appear one time.<br/>
 *  - all given values must appear one time.<br/>
 *  
 * To initialize :
 * <ul>
 * 	<li>
 * 	<u><b>By annotations :</b></u> Use {@link Validate} and use the <code>contains</code> attribute to 
 * specify all substrings values to check.<br/>
 * By default, the strategy is at least one must appear. To switch the strategy, put the attribute 
 * <code>mustContainsAll</code> to true.
 * 	</li>
 * 	<li>
 * 	<u><b>By Xml :</b></u>
 * <ul>
 * <li>
 * To add the contains validation, see the example below : <br/>
 * <code>
 * &lt;ToMap field="..."><br/>
 * <b>
 * &nbsp;&nbsp;&nbsp;&lt;contains mustContainsAll="true"><br/>
 * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;value>aze&lt;/value><br/>
 * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...<br/>
 * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;value>poi&lt;/value><br/>
 * &nbsp;&nbsp;&nbsp;&lt;/contains><br/>
 * </b>
 * &lt;/ToMap><br/>
 * </code>
 * This example shows an example with the second strategy. To retrieve the first strategy, just put the attribute
 * mustContainsAll at false or remove the attribute.
 * </li>
 * </ul>
 * 
 * @author msoares
 *
 */
public class StringContainsValidator extends AbstractSubStringsRequiredValidator {

	public StringContainsValidator() {}
	
	public StringContainsValidator(List<String> substrings) {
		super(substrings);
	}
	public StringContainsValidator(String... substrings) {
		super(substrings);
	}
	public StringContainsValidator(List<String> substrings, boolean atLeastOne) {
		super(substrings, SubStringMatcherValidationStrategy.CONTAINS, atLeastOne);
	}

	@Override
	public boolean init(Context context, Field field) {
		Validate annotation = field.getAnnotation(Validate.class);
		if(annotation == null || annotation.contains().length == 0)
			return false;		
		super.init(Arrays.asList(annotation.contains()), SubStringMatcherValidationStrategy.CONTAINS, annotation.atLeastOne());
		return true;
	}

	@Override
	public boolean init(Context context, Field field, XmlValidator xmlValidator) {
		XmlContainsValidator xmlContains = (XmlContainsValidator) xmlValidator;
		List<String> strings = new ArrayList<String>();
		for(String value : xmlContains.getValues()) {
			strings.add(value);
		}
		super.init(strings, SubStringMatcherValidationStrategy.CONTAINS, xmlContains.isAtLeastOne());
		return true;
	}

}
